package com.gitee.ixtf.rsocket

import com.gitee.ixtf.rsocket.kotlinx.payload
import com.gitee.ixtf.rsocket.kotlinx.readJson
import com.gitee.ixtf.rsocket.kotlinx.withData
import com.gitee.ixtf.rsocket.service.GetBrokerServiceRequest
import com.gitee.ixtf.rsocket.service.GetBrokerServiceResponse
import com.gitee.ixtf.rsocket.service.ListBrokerServiceRequest
import io.cloudevents.core.builder.CloudEventBuilder
import io.vertx.core.json.JsonObject
import reactor.util.retry.Retry

interface IBrokerAgent : IRSocketAgent {
  suspend fun ping(service: String): Boolean

  suspend fun getBrokerService(service: String): GetBrokerServiceResponse =
      requestResponseBroker {
            withType(GetBrokerServiceRequest.CLOUD_EVENT_TYPE)
            withData(JsonObject.mapFrom(GetBrokerServiceRequest(service)))
          }
          .readJson()

  suspend fun listBrokerService(): Collection<GetBrokerServiceResponse> =
      requestResponseBroker { withType(ListBrokerServiceRequest.CLOUD_EVENT_TYPE) }.readJson()

  suspend fun metadataPushBroker(
      retry: Retry? = null,
      block: suspend CloudEventBuilder.() -> CloudEventBuilder
  ) = metadataPush(retry) { block(this).payload(BROKER_ROUTE) }

  suspend fun fireAndForgetBroker(
      retry: Retry? = null,
      block: suspend CloudEventBuilder.() -> CloudEventBuilder
  ) = fireAndForget(retry) { block(this).payload(BROKER_ROUTE) }

  suspend fun requestResponseBroker(
      retry: Retry? = null,
      block: suspend CloudEventBuilder.() -> CloudEventBuilder
  ) = requestResponse(retry) { block(this).payload(BROKER_ROUTE) }

  suspend fun requestStreamBroker(
      retry: Retry? = null,
      block: suspend CloudEventBuilder.() -> CloudEventBuilder
  ) = requestStream(retry) { block(this).payload(BROKER_ROUTE) }
}
